Skip to content

Conversation

ShivaHuang
Copy link

Summary

Fixes an issue where JSONEncoder incorrectly applied key encoding strategies (like .convertToSnakeCase) to dictionary keys that implement CodingKeyRepresentable, when these keys should preserve their semantic meaning and remain unchanged.

Problem

When encoding dictionaries with CodingKeyRepresentable keys (e.g., custom enum or struct keys), JSONEncoder was treating them as regular coding key values and applying key conversion strategies. This caused keys like "leaveMeAlone" to be transformed to "leave_me_alone" even when the key itself represents a semantic identifier that should remain unchanged.

Solution

  • Expands the existing _JSONStringDictionaryEncodableMarker protocol to cover any CodingKeyRepresentable-keyed dictionaries, not just String-keyed ones.
  • Renames the protocol to _JSONCodingKeyRepresentableDictionaryEncodableMarker to reflect its broader scope.
  • Updates the encoding logic to convert CodingKeyRepresentable keys directly to their string representation without applying encoding transformations.

Test Plan

Added test case encodingDictionaryCodingKeyRepresentableKeyConversionUntouched() that verifies:

  • Dictionary with CodingKeyRepresentable keys preserves original key names.
  • Key encoding strategies like .convertToSnakeCase are not applied to the dictionary keys.
  • The fix works with custom structs implementing CodingKeyRepresentable.

Checklist

  • Added test coverage for the fix
  • All existing tests pass
  • Code follows Swift Foundation conventions
  • Changes are backward compatible

This change ensures that dictionaries with semantic keys maintain their intended structure while still allowing key
encoding strategies to work correctly for object properties during regular encoding.

…keys

When encoding dictionaries with CodingKeyRepresentable keys (e.g., custom
enum or struct keys), JSONEncoder was incorrectly applying key encoding
strategies like convertToSnakeCase to the dictionary keys themselves,
rather than treating them as semantic keys that should remain unchanged.

This change:
- Expands _JSONStringDictionaryEncodableMarker protocol coverage from
  String-keyed dictionaries to any CodingKeyRepresentable-keyed dictionaries
- Renames the protocol to _JSONCodingKeyRepresentableDictionaryEncodableMarker
  to better reflect its expanded scope
- Updates the encoding logic to handle CodingKeyRepresentable keys by
  converting them directly to their string representation

Fixes encoding behavior where Dictionary<CustomKey, Value> keys were
being transformed (e.g., "leaveMeAlone" -> "leave_me_alone") when they
should preserve their original form.
@ShivaHuang ShivaHuang changed the title Fix JSONEncoder key conversion for CodingKeyRepresentable dictionary keys Fix JSONEncoder key conversion for CodingKeyRepresentable dictionary keys Sep 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant